﻿using FreeScheduler;
using Google.Protobuf.WellKnownTypes;
using Newtonsoft.Json.Serialization;
using PosClient.Helper;
using PosClient.Interfaces;
using PosClient.Model;
using PosClient.Service;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using TimeCrontab;

namespace PosClient.Job
{
    public class JobManager
    {
        Scheduler scheduler = new FreeSchedulerBuilder()
            .OnExecuting(task =>
            {
                using (var conn = FreeClient.Sqlite)
                {
                    var job = conn.Select<JobEntity>().Where(x => x.JobStatus == 1 && x.Deleted == 0 && x.JobName == task.Topic && x.JobBody == task.Body).ToList().FirstOrDefault();
                    var reflection = ToolService.ReflectionProGrom<IJob>($"Job.DownLoad.{job.JobClass}");
                    var result = reflection.Excute();
                    if (result.Success)
                    {
                        Console.WriteLine($"{result.Message} 被执行");
                    }
                }
                Console.WriteLine($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] {task.Topic} 被执行");
                Logger.Default.Audit($"[{DateTime.Now.ToString("HH:mm:ss.fff")}] {task.Topic} 被执行");
                task.Remark("log..");
            })
            .UseCustomInterval(task =>
            {
                //利用 cron 功能库解析 task.IntervalArgument 得到下一次执行时间
                //与当前时间相减，得到 TimeSpan，若返回 null 则任务完成
                var crontab = Crontab.Parse(task.IntervalArgument, CronStringFormat.WithSeconds);
                var nextOccurrence = crontab.GetNextOccurrence(DateTime.Now);
                TimeSpan timeDifference = nextOccurrence - DateTime.Now;
                return TimeSpan.FromTicks(timeDifference.Ticks);
            })
            .Build();

        public JobManager()
        {
        }

        public void StartAsync(JobEntity job)
        {
            scheduler.ResumeTask(job.JobCode);
        }

        public void StopAsync(JobEntity job)
        {
            scheduler.PauseTask(job.JobCode);
        }

        public void LoadJob()
        {
            if (Datafeed.GetPage(scheduler, null, null, null, null).Total == 0)
            {
                using (var conn = FreeClient.Sqlite)
                {
                    var jobs = conn.Select<JobEntity>().Where(x => x.Deleted == 0 && x.JobStatus == 1).ToList();
                    if (jobs.Count > 0)
                    {
                        foreach (var job in jobs)
                        {
                            string jobCode = scheduler.AddTaskCustom(job.JobName,job.JobBody,job.JobCron);
                            conn.Update<JobEntity>()
                                .Set(it => it.JobCode, jobCode)
                                .Where(x => x.JobName == job.JobName && x.JobBody == job.JobBody)
                                .ExecuteAffrows();
                        }
                    }
                }
            }
        }

    }
}
